package com.indusfo.spc.service.impl;

import com.indusfo.spc.exception.GlobalException;
import com.indusfo.spc.exception.ModifyFailedException;
import com.indusfo.spc.exception.ParamsErrorException;
import com.indusfo.spc.mapper.ProductLineMapper;
import com.indusfo.spc.mapper.RoleMapper;
import com.indusfo.spc.mapper.WorkPermissionMapper;
import com.indusfo.spc.pojo.*;
import com.indusfo.spc.service.*;
import com.indusfo.spc.vo.AssociTionTreeNode;
import com.indusfo.spc.vo.JSONObject;
import com.indusfo.spc.vo.SimpleTreeNode;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色定义表业务层
 *
 * @author 贺闻博
 * <p>
 * 2018年11月28日
 */
@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    private static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RoleRightService roleRightService;
    @Resource
    private AssocitionService associtionService;
    @Resource
    private RoleUserService roleUserService;
    @Resource
    private MenuService menuService;
    @Resource
    private ProductLineMapper productLineMapper;
    @Resource
    private StationService stationService;
    @Resource
    private WorkPermissionMapper workPermissionMapper;

    public static final int TD_ID = 101025;
    public static final int TD_DEP_ITEM_ID = 3;
    private int flag = 1;

    /**
     * 查询所有角色功能
     */
    @Override
    public JSONObject selectRoleS(Role role) {
        List<Role> listRole = null;
        try {
            Integer pageSize = role.getPagesize();
            Integer pageIndex = role.getPageindex();
            if (pageSize != null && pageIndex != null) {
                role.setIncept(pageSize * (pageIndex - 1));
            }
            Integer lRoleId = role.getRoleId();
            if (lRoleId == null) {
                listRole = roleMapper.selectRoles(role);
//                System.out.println(listRole);
            } else {
                listRole = roleMapper.selectRole(lRoleId);
//                System.out.println(listRole);
            }
//            if (listRole.isEmpty()) {
//                throw new ModifyFailedException("没有找到角色相关数据!");
//            }
            int count = roleMapper.getCounts(role);
            return JSONObject.oK("查询成功", listRole, count);
        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return JSONObject.build(500, e.getMessage());
        }
    }

    /**
     * 更新新增角色信息
     */
    @Override
    public JSONObject updateRole(Role role) {
        try {
            checkParams(role);
            // role.setUserId(UserThreadLocal.get().getlUserId());
            if (role.getRoleId() == null) {
                Integer out = roleMapper.insertRole(role);
                Integer num = role.getRoleId();
                if (out == 0) {
                    throw new ModifyFailedException("新增数据失败");
                }
                System.out.println(num);
                return JSONObject.build(200, "新增数据成功", num);
            } else {
                Integer num = roleMapper.updateByPrimaryKeySelective(role);
                if (num == 0) {
                    throw new ModifyFailedException("更新数据失败");
                }
                return JSONObject.build(200, "更新数据成功", num);
            }

        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return JSONObject.build(500, e.getMessage());
        }
    }

    /**
     * 参数校验
     *
     * @author xuz
     * @date 2019/7/9 3:09 PM
     * @param role
     * @return void
     */
    private void checkParams(Role role) {
        if(role.getRoleId()!=null) {
            if (role.getRoleId() == 1) {
                throw new ModifyFailedException("超级用户不能被编辑");
            }
        }
        if (role.getRoleName() == null) {
            throw new ModifyFailedException("角色名称不能为空");
        }

        int counts = roleMapper.getRepeatCounts(role);
        if (counts > 0) {
            throw new ParamsErrorException("该角色名已存在，请不要重复添加");
        }
    }

    /**
     * 删除角色 信息
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String deleteRole(Long[] lRoleIds, Integer lDataState) {
        try {
            if (null == lRoleIds) {
                throw new ParamsErrorException("请选择要删除的角色");
            }
            if ("1".equals(lRoleIds)) {
                throw new ModifyFailedException("超级用户不能被删除");
            }
            if (lDataState == null) {
                throw new ModifyFailedException("数据状态不能为空");
            }
            int num = roleMapper.deleteRole(lRoleIds, lDataState);
            String msg = "";
            if ( 0 == num ) {
                switch (lDataState) {
                    case 1:
                        throw new ModifyFailedException("启用失败");
                    case 2:
                        throw new ModifyFailedException("删除失败");
                    case 3:
                        throw new ModifyFailedException("停用失败");
                    default:
                        break;
                }
            } else {
                switch (lDataState) {
                    case 1:
                        msg = "启用成功";
                        break;
                    case 2:
                        msg = "删除成功";
                        break;
                    case 3:
                        msg = "停用成功";
                        break;
                    default:
                        break;
                }
            }

            // ------------------------------------ 其他表操作begin -------------------------------------- //
            if (lDataState == 2) {
                // 删除其他权限表关联数据，逻辑删除
                roleRightService.deleteRoleRightByRoleId(lRoleIds, lDataState);
                associtionService.deleteAssociTionByRoleId(lRoleIds, lDataState);
                roleUserService.deleteRoleUserByRoleId(lRoleIds, lDataState);
            }

            // ------------------------------------ 其他表操作end -------------------------------------- //
            return msg;

        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return e.getMessage();
        }

    }

    //---------------------------------- begin --------------------------------------//

    /**
     * 新增角色
     * 1. 新增角色信息
     * 2. 新增菜单权限集合
     * 3. 新增数据权限集合
     * 4. 新增用户权限集合
     * 5. 新增作业授权集合
     *
     * @author xuz
     * @date 2019/7/9 1:44 PM
     * @param roleBo
     * @return java.lang.String
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String insertRoleVo(RoleBO roleBo) {
        if (null == roleBo) {
            throw new ParamsErrorException("传入对象不能为空");
        }
        //1. 新增角色信息
        Role role = setRoleData(roleBo);
        // 获取新增角色的角色ID
        int roleId = insertRole(role);

        //2. 新增菜单权限集合
        List<String> vcMenuCodeList = roleBo.getVcMenuCodeList();
        if (null != vcMenuCodeList) {
            for (String vcMenuCode : vcMenuCodeList) {
                insertRoleRight(roleId, vcMenuCode);
            }
        }

        //3. 新增数据权限集合
        List<Integer> lDepList = roleBo.getlDepList();
        if (null != lDepList) {
            for (Integer lDepId : lDepList) {
                insertAssocition(roleId, lDepId);
            }
        }

        //4. 新增用户权限集合
        List<Integer> lUserIdList = roleBo.getlUserIdList();
        if (null != lUserIdList) {
            for (Integer lUserId : lUserIdList) {
                insertRightUser(roleId, lUserId);
            }
        }

        //5. 新增作业授权集合
        List<Integer> staIdList = roleBo.getStaIdList();
        if (null != staIdList) {
            for (Integer staId : staIdList) {
                insertWorkPermission(roleId, staId);
            }
        }

        return "新增成功";
    }

    /**
     * 新增角色基础信息
     * 得到新增的角色ID
     *
     * @author xuz
     * @date 2019/7/9 3:08 PM
     * @param role
     * @return int
     */
    private int insertRole(Role role) {
        checkParams(role);
        int count = roleMapper.insertRole(role);
        if (count <= 0) {
            throw new ParamsErrorException("新增失败");
        }
        return role.getRoleId();
    }

    /**
     * 更新角色
     * 1. 删除并新增角色信息
     * 2. 删除并新增菜单权限集合
     * 3. 删除并新增数据权限集合
     * 4. 删除并新增用户权限集合
     * 5. 删除并新增作业授权集合
     *
     * @author xuz
     * @date 2019/7/9 4:10 PM
     * @param roleBo
     * @return java.lang.String
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String updateRoleVO(RoleBO roleBo) {
        if (null == roleBo) {
            throw new ParamsErrorException("传入对象不能为空");
        }
        if (null == roleBo.getRoleId()) {
            throw new ParamsErrorException("角色ID不能为空");
        }

        //1. 更新角色信息
        Role role = setRoleData(roleBo);
        int roleId = updateRoleData(role);

        //2. 新增菜单权限集合
        List<String> vcMenuCodeList = roleBo.getVcMenuCodeList();
        // 先删除数据
        roleRightService.deleteRight(roleId);
        if (null != vcMenuCodeList) {
            for (String vcMenuCode : vcMenuCodeList) {
                insertRoleRight(roleId, vcMenuCode);
            }
        }

        //3. 新增数据权限集合
        // 先删除数据
        associtionService.deleteAssociTionAll(roleId);
        List<Integer> lDepList = roleBo.getlDepList();
        if (null != lDepList) {
            for (Integer lDepId : lDepList) {
                insertAssocition(roleId, lDepId);
            }
        }

        //4. 新增用户权限集合
        List<Integer> lUserIdList = roleBo.getlUserIdList();
        // 先删除数据
        roleUserService.deleteRoleUserAll(roleId);
        if (null != lUserIdList) {
            for (Integer lUserId : lUserIdList) {
                insertRightUser(roleId, lUserId);
            }
        }

        //5. 新增作业授权集合
        List<Integer> staIdList = roleBo.getStaIdList();
        // 先删除数据
        workPermissionMapper.deleteByRoleId(roleId);
        if (null != staIdList) {
            for (Integer staId : staIdList) {
                insertWorkPermission(roleId, staId);
            }
        }

        return "更新成功";
    }

    /**
     * 更新角色基础信息
     * 得到新增的角色ID
     *
     * @param role
     * @return int
     * @author xuz
     */
    private int updateRoleData(Role role) {
        checkParams(role);
        int count = roleMapper.updateByPrimaryKeySelective(role);
        if (count <= 0) {
            throw new ParamsErrorException("更新失败");
        }
        return role.getRoleId();
    }

    /**
     * 查询权限列表
     * 无ID，查询权限列表树(无勾选)，传入ID，查询权限列表树(该角色下的权限勾选状态)
     * 1. 角色信息
     * 2. 菜单权限集合
     * 3. 数据权限集合
     * 4. 用户权限集合
     * 5. 作业授权集合
     *
     * @author xuz
     * @date 2019/7/10 2:38 PM
     * @param lRoleId
     * @return com.indusfo.spc.pojo.RoleVO
     */
    @Override
    public RoleVO queryRoleVO(Integer lRoleId) {
        RoleVO roleVO = new RoleVO();
//        if (null == lRoleId) {
//            throw new ParamsErrorException("角色ID不能为空");
//        }

        //1.1 查询角色信息
        Integer lDataPermission = null;
        if (null != lRoleId) {
            List<Role> roleList = roleMapper.selectRole(lRoleId);
            if (null==roleList && roleList.size()<=0) {
                return null;
            }
            //1.2 封装角色信息
            Role role = roleList.get(0);
            lDataPermission = role.getDataPermission();
            roleVO.setRoleId(role.getRoleId());
            roleVO.setUserId(role.getUserId());
            roleVO.setDataPermission(lDataPermission);
            roleVO.setRoleName(role.getRoleName());
            roleVO.setDataPermissionName(role.getDataPermissionName());
            roleVO.setRemark(role.getRemark());
        }


        //2. 获取菜单权限树，并封装
        getMenuTree(lRoleId, roleVO);

        //4.1 获取用户权限
        List<RoleUser> roleUserList = new ArrayList<>();
        if (null != lRoleId) {
            roleUserList = roleUserService.queryRoleUserByRoleId(lRoleId);
        }
        //4.2 封装用户权限
        roleVO.setRoleUserList(roleUserList);

        //5. 获取作业授权树，并封装
        //5.1 查询角色拥有的作业权限集合
        List<Integer> stationIdList = new ArrayList<>();
        if (null != lRoleId) {
            stationIdList = roleMapper.getStationByRoleId(lRoleId);
        }
        getWorkPermissonTree(stationIdList, roleVO);

        return roleVO;
    }

    /**
     * 获取菜单权限树，并封装
     *
     * @param lRoleId
     * @param roleVO
     * @return void
     * @author xuz
     * @date 2019/7/17 1:40 PM
     */
    private void getMenuTree(Integer lRoleId, RoleVO roleVO) {
        //2.1 查询角色拥有的菜单权限
        List<RoleRight> roleRightList = new ArrayList<>();
        if (null != lRoleId) {
            roleRightList = roleRightService.queryRoleRightByRoleId(lRoleId);
        }
        List<String> menuRight = roleRightList.stream().map(roleRight -> {
            return roleRight.getVcMenuCode();
        }).collect(Collectors.toList());
        //2.2 获取菜单权限树
        List<SimpleTreeNode> menuTree = menuService.getMenuTree(menuRight);
        //2.3 封装菜单权限树
        roleVO.setMenuTreeList(menuTree);
    }

    /**
     * 获取作业授权树
     *
     * @param stationIdList , roleVO
     * @param stationIdList
     * @return void
     * @author xuz
     */
    private void getWorkPermissonTree(List<Integer> stationIdList, RoleVO roleVO) {
        //5.2 查询产线集合
        List<ProductLine> productLineList = productLineMapper.listProductLines(null);
        //5.3 获取作业授权树
        List<AssociTionTreeNode> workPermissionTreeNodeList =
                productLineList.stream().map(productLine -> {
                    Integer lProductionLineId = productLine.getLProductionLineId();
                    String vcProductionLineName = productLine.getVcProductionLineName();
                    String vcProductionLineCode = productLine.getVcProductionLineCode();
                    // 根据产线ID查询工位集合
                    List<Station> stationList = stationService.getByProductionLineId(lProductionLineId);
                    List<AssociTionTreeNode> stationTreeNodeList = stationList.stream().map(station -> {
                        AssociTionTreeNode workPermissionTreeNode = new AssociTionTreeNode();
                        Integer staId = station.getStaId();
                        String staName = station.getStaName();
                        workPermissionTreeNode.setId(staId);
                        workPermissionTreeNode.setTitle(staName);
                        workPermissionTreeNode.setpId(lProductionLineId);
                        if (null!=staId && stationIdList.contains(staId)) {
                            workPermissionTreeNode.setChecked(true);
                        }
                        workPermissionTreeNode.setFlag(2);
                        return workPermissionTreeNode;
                    }).collect(Collectors.toList());

                    AssociTionTreeNode workPermissionTreeNode = new AssociTionTreeNode();
                    workPermissionTreeNode.setId(lProductionLineId);
                    workPermissionTreeNode.setTitle(vcProductionLineName);
                    workPermissionTreeNode.setCode(vcProductionLineCode);
                    workPermissionTreeNode.setChildren(stationTreeNodeList);
                    workPermissionTreeNode.setFlag(1);
                    return workPermissionTreeNode;
                // 排序
                }).sorted(Comparator.comparingInt(AssociTionTreeNode::getId)).collect(Collectors.toList());
        //5.4 封装
        roleVO.setWorkPermissionList(workPermissionTreeNodeList);
    }

    /**
     * 角色信息数据封装
     *
     * @author xuz
     * @date 2019/7/9 2:04 PM
     * @param roleBo
     * @return com.indusfo.spc.pojo.Role
     */
    private Role setRoleData(RoleBO roleBo) {
        Role role = new Role();
        role.setRoleId(roleBo.getRoleId());
        role.setRoleName(roleBo.getRoleName());
        role.setUserId(roleBo.getUserId());
        role.setDataPermission(roleBo.getDataPermission());
        role.setDataState(1);
        role.setRemark(roleBo.getRemark());
        return role;
    }

    /**
     * 新增作业授权
     *
     * @param roleId
     * @param staId
     * @return void
     * @author xuz
     */
    private void insertWorkPermission(int roleId, Integer staId) {
        WorkPermission workPermission = new WorkPermission();
        workPermission.setlRoleId(roleId);
        workPermission.setStaId(staId);
        workPermission.setDataState(1);
        workPermissionMapper.insertSelective(workPermission);
    }

    /**
     * 新增用户权限
     *
     * @param roleId
     * @param lUserId
     * @return void
     * @author xuz
     * @date 2019/7/17 2:15 PM
     */
    private void insertRightUser(int roleId, Integer lUserId) {
        RoleUser roleUser = new RoleUser();
        roleUser.setRoleId(roleId);
        roleUser.setUserId(lUserId);
        roleUser.setFightFlag(1);
        roleUser.setDataState(1);
        roleUserService.insertRoleUser(roleUser);
    }

    /**
     * 新增数据权限
     *
     * @author xuz
     * @date 2019/7/12 2:19 PM
     * @param roleId, lDepId
     * @return void
     */
    private void insertAssocition(int roleId, Integer lDepId) {
        AssociTion associTion = new AssociTion();
        associTion.setlRoleId(roleId);
        associTion.setlDepId(lDepId);
        associTion.setlDataState(1);
        associtionService.insertAssociTion(associTion);
    }

    /**
     * 新增菜单权限
     *
     * @author xuz
     * @date 2019/7/12 2:18 PM
     * @param roleId, vcMenuCode
     * @return void
     */
    private void insertRoleRight(int roleId, String vcMenuCode) {
        RoleRight roleRight = new RoleRight();
        roleRight.setlRoleId(roleId);
        roleRight.setVcMenuCode(vcMenuCode);
        roleRight.setlFightFlag(1);
        roleRight.setlOperation(1);
        roleRight.setlDataState(1);
        roleRightService.updateRoleRight(roleRight);
    }
    //---------------------------------- end --------------------------------------//
}
